<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
		<title>游戏</title>
		<script src="js/jquery-1.11.1.min.js"></script>
		<script src="js/adapter.js"></script>
		<style type="text/css">
			body {
				width: 100%;
				height: 100%;
				margin: 0px;
				background-color: white;
			}
			
			#remoteVideo {
				background-color: white;
			}
			
			button {
				float: left;
				clear: right;
			}
			
			.trans90 {
				/* Rotate div */
				transform: rotate(9deg);
				-ms-transform: rotate(90deg);
				/* Internet Explorer */
				-moz-transform: rotate(90deg);
				/* Firefox */
				-webkit-transform: rotate(90deg);
				/* Safari 和 Chrome */
				-o-transform: rotate(90deg);
				/* Opera */
			}
			/*伪元素，设置全屏时不显示控件*/
			
			video::-webkit-media-controls-enclosure {
				display: none;
			}
			
			video::-moz-media-controls-enclosure {
				display: none;
			}
			
			video::media-controls-enclosure {
				display: none;
			}
		</style>
		<script>
			$(document).ready(function() {
				//div 's relative position'
				var offset = $("#remoteVideo").offset();
				var mainScreen = $("#remoteVideo")[0];
				var mOrientation = 0;
				$(window).on("orientationchange", function() {
					mOrientation = window.orientation;
					if(window.orientation == 0) // Portrait
					{
						console.log("竖屏状态");
					} else // Landscape
					{
						console.log("横屏状态");
					}
				});

				function touchMove(event) {
					event.preventDefault();
					if(!event.touches.length) return;
					var touch = event.touches[0];
					sendTouchEvent(touch, "TOUCH_MOVE");
				};

				function touchStart(event) {
					event.preventDefault();
					if(!event.touches.length) return;
					var touch = event.touches[0];
					sendTouchEvent(touch, "TOUCH_START");

				};

				function sendTouchEvent(touch, eventType) {
					//videoWidth、videoHeight、width和height的大小切屏不会改变大小
					//暂不考虑非全屏时横屏坐标 0 90（正常横放） -90 （机顶在右侧）
					//全屏模式下 touch.pageX/Y 不用参考offset
					trace(mOrientation);
					var remoteVideo=document.getElementById("remoteVideo");
					//暂不考虑videoWidth>videoHeight时mOrientation == 0的全屏情况
					if(mOrientation == 0) {
						var currentWidth = remoteVideo.width;
						var currentHeight = (remoteVideo.width / remoteVideo.videoWidth * remoteVideo.videoHeight);
//						trace("当前总宽度" + currentWidth + "当前总高度:" + currentHeight);
						var relativeX = (touch.pageX - offset.left);
						var relativeY = (touch.pageY - offset.top);
						//判断是否为全屏 全屏下位置为 touch.pageY-(window.screen.height-currentWidth)/2
						var posX = relativeX;
						if(isFullScreen()) {
							//全屏情况下要考虑videoWidth>videoHeigh
							if(remoteVideo.videoWidth<=remoteVideo.videoHeight){
								//console.log("touch.pageY:"+touch.pageY+" window.screen.height:"+window.screen.height+" remoteVideo.videoHeight:"+remoteVideo.videoHeight+" relativeY:"+relativeY);
								var posY = (touch.pageY - (window.screen.height - currentHeight) / 2);
								//console.log("x:" + relativeX + " y:" + posY+ " type:"+eventType+" full");
								var floatX = posX < 0 ? 0 : (posX > currentWidth ? 1 : posX / currentWidth);
								var floatY = posY < 0 ? 0 : (posY > currentHeight ? 1 : posY / currentHeight);
								console.log("发送结果：横坐标：" + floatX + " 纵坐标" + floatY + "类型:" + eventType);
								trace("发送结果：横坐标：" + floatX + " 纵坐标" + floatY + "类型:" + eventType);
							}else{
								var posY = relativeX;
								var posX = currentHeight-(touch.pageY-(window.screen.height - currentHeight) / 2);
								var floatX = posX < 0 ? 0 : (posX > currentHeight ? 1 : posX / currentHeight);
								var floatY = posY < 0 ? 0 : (posY > currentWidth ? 1 : posY / currentWidth);
								console.log("发送结果：横坐标：" + floatX + " 纵坐标" + floatY + "类型:" + eventType);
								trace("发送结果：横坐标：" + floatX + " 纵坐标" + floatY + "类型:" + eventType);
							}
						} else {
							//console.log("x:" + relativeX + " y:" + relativeY + " type:"+eventType+" nofull");
							if(remoteVideo.videoWidth<=remoteVideo.videoHeight){
								var posY = relativeY;
								var floatX = posX < 0 ? 0 : (posX > currentWidth ? 1 : posX / currentWidth);
								var floatY = posY < 0 ? 0 : (posY > currentHeight ? 1 : posY / currentHeight);
								console.log("发送结果：横坐标：" + floatX + " 纵坐标" + floatY + "类型:" + eventType);
								trace("发送结果：横坐标：" + floatX + " 纵坐标" + floatY + "类型:" + eventType);
							}else{
								var posY = relativeX;
								var posX = currentHeight-relativeY;
								var floatX = posX < 0 ? 0 : (posX > currentHeight ? 1 : posX / currentHeight);
								var floatY = posY < 0 ? 0 : (posY > currentWidth ? 1 : posY / currentWidth);
								console.log("发送结果：横坐标：" + floatX + " 纵坐标" + floatY + "类型:" + eventType);
								trace("发送结果：横坐标：" + floatX + " 纵坐标" + floatY + "类型:" + eventType);
							}
							
						}
						
					} else if(mOrientation == 90) {
						//目前只考虑全屏的情况
						//width和height说法还是和手机保持一致 不受影响
						//videoWidth、videoHeight、width和height的大小与横屏时保持一致 640 480
						var currentWidth = remoteVideo.width;
						var currentHeight = ( remoteVideo.videoWidth / remoteVideo.videoHeight)*remoteVideo.width;
//						trace("当前总宽度" + currentWidth + "当前总高度:" + currentHeight);//360 480
//						trace("touch.pageX:"+touch.pageX+" touch.pageY:"+touch.pageY);
						var posX = currentWidth-touch.pageY;
						//横屏下 window.screen.width得到的 手机的高度的那个分辨率而不是宽度
						var posY = touch.pageX-(window.screen.width-currentHeight)/2;
						//还得考虑videoHeight>videoWidth，非全屏的情况 这边不写了
						if(isFullScreen()) {
//							trace("posX:"+posX+" posY"+posY);
//							trace("touch.pageX:"+touch.pageX+" window.screen.width:"+window.screen.width+" currentHeight:"+currentHeight);
							var floatX = posX < 0 ? 0 : (posX > currentWidth ? 1 : posX / currentWidth);
							var floatY = posY < 0 ? 0 : (posY > currentHeight ? 1 : posY / currentHeight);
							console.log("发送结果：横坐标：" + floatX + " 纵坐标" + floatY + "类型:" + eventType);
							trace("发送结果：横坐标：" + floatX + " 纵坐标" + floatY + "类型:" + eventType);
						}
					} else if(mOrientation == -90) {
						var currentWidth = remoteVideo.width;
						var currentHeight = ( remoteVideo.videoWidth / remoteVideo.videoHeight)*remoteVideo.width;
						var posX = currentWidth-touch.pageY;
						//需要window.screen.width去减
						var posY = touch.pageX-(window.screen.width-currentHeight)/2; 
						//还得考虑videoHeight>videoWidth的情况 这边不写了
						if(isFullScreen()) {
//							trace("posX:"+posX+" posY"+posY);
//							trace("touch.pageX:"+touch.pageX+" window.screen.width:"+window.screen.width+" currentHeight:"+currentHeight);
							var floatX = posX < 0 ? 0 : (posX > currentWidth ? 1 : posX / currentWidth);
							var floatY = posY < 0 ? 0 : (posY > currentHeight ? 1 : posY / currentHeight);
							console.log("发送结果：横坐标：" + floatX + " 纵坐标" + floatY + "类型:" + eventType);
							trace("发送结果：横坐标：" + floatX + " 纵坐标" + floatY + "类型:" + eventType);
						} 
					}

				}

				function touchEnd() {
					console.log("type:end");
				}
				mainScreen.addEventListener("touchmove", touchMove, false);
				mainScreen.addEventListener("touchstart", touchStart, false);
				mainScreen.addEventListener("touchend", touchEnd, false);
			});
		</script>
		<script>
			var request = null;
			var hangingGet = null;
			var localName;
			var server;
			var my_id = -1;
			//记录其他peer
			var other_peers = {};
			var message_counter = 0;

			// added stuff start 
			var pc;
			//constraints for desktop browser 
			var desktopConstraints = {

				video: {
					mandatory: {
						maxWidth: 800,
						maxHeight: 600
					}
				},

				audio: true
			};

			//constraints for mobile browser 
			var mobileConstraints = {

				video: {
					mandatory: {
						maxWidth: 480,
						maxHeight: 320,
					}
				},

				audio: true
			}

			//if a user is using a mobile browser 
			if(/Android|iPhone|iPad/i.test(navigator.userAgent)) {
				var constraints = mobileConstraints;
			} else {
				var constraints = desktopConstraints;
			}
			var remoteStream;

			function trace(txt) {
				var elem = document.getElementById("debug");
				elem.innerHTML += txt + "<br>";
			}

			function sendToPeer(peer_id, data) {
				if(my_id == -1) {
					alert("Not connected");
					return;
				}
				if(peer_id == my_id) {
					alert("Can't send a message to oneself :)");
					return;
				}
				var r = new XMLHttpRequest();
				r.open("POST", server + "/message?peer_id=" + my_id + "&to=" + peer_id,
					false);
				r.setRequestHeader("Content-Type", "text/plain");
				r.send(data);
				console.log(peer_id, " Send ", data);
				trace(peer_id + " Send :" + data);
				var dataJson = JSON.parse(data);
				console.log(peer_id, " send ", data);
				r = null;
			}
			var onSessionConnecting = function(message) {

				console.log("Session connecting.");
				trace("Session connecting.");
			}

			var onSessionOpened = function(message) {
				console.log("Session opened.");
				trace("Session opened.");
			}

			var onRemoteStreamRemoved = function(event) {
					console.log("Remote stream removed.");
					trace("Remote stream removed.");
				}
				// 进入全屏
			function launchFullScreen(element) {
				if(element.requestFullscreen) {
					element.requestFullscreen();
				} else if(element.mozRequestFullScreen) {
					element.mozRequestFullScreen();
				} else if(element.webkitRequestFullscreen) {
					element.webkitRequestFullscreen();
				} else if(element.msRequestFullscreen) {
					element.msRequestFullscreen();
				}
			}
			//退出全屏
			function cancelFullScreen() {
				if(document.cancelFullScreen) {
					document.cancelFullScreen();
				} else if(document.mozCancelFullScreen) {
					document.mozCancelFullScreen();
				} else if(document.webkitCancelFullScreen) {
					document.webkitCancelFullScreen();
				}
			}
			//反射調用
			var invokeFieldOrMethod = function(element, method) {
					var usablePrefixMethod;
					["webkit", "moz", "ms", "o", ""].forEach(function(prefix) {
						if(usablePrefixMethod) return;
						if(prefix === "") {
							// 无前缀，方法首字母小写
							method = method.slice(0, 1).toLowerCase() + method.slice(1);
						}
						var typePrefixMethod = typeof element[prefix + method];
						if(typePrefixMethod + "" !== "undefined") {
							if(typePrefixMethod === "function") {
								usablePrefixMethod = element[prefix + method]();
							} else {
								usablePrefixMethod = element[prefix + method];
							}
						}
					});

					return usablePrefixMethod;
				}
				//判断是否是全屏
			function isFullScreen() {
				return invokeFieldOrMethod(document, 'FullScreen') || invokeFieldOrMethod(document, 'IsFullScreen') || document.IsFullScreen;
			}
			var createPeerConnection = function(connectionId) {
				var pc_config = {
					"iceServers": [{
						"url": "stun:stun.l.google.com:19302"
					}]
				};
				try {
					console.log(pc_config);
					trace(pc_config);
					// 创建PeerConnection实例 (参数为null则没有iceserver，即使没有stunserver和turnserver，仍可在局域网下通讯)
					pc = new RTCPeerConnection(pc_config);
					// 发送ICE候选到其他客户端
					pc.onicecandidate = function(event) {
						if(event.candidate) {
							var msgCANDIDATE = {};
							msgCANDIDATE.sdpMLineIndex = event.candidate.sdpMLineIndex;
							msgCANDIDATE.sdpMid = event.candidate.sdpMid;
							msgCANDIDATE.candidate = event.candidate.candidate;
							sendToPeer(connectionId, JSON.stringify(msgCANDIDATE));
						} else {
							console.log("End of candidates.");
							trace("End of candidates.");
						}
					};
					pc.onconnecting = onSessionConnecting;
					pc.onopen = onSessionOpened;
					// 如果检测到媒体流连接到本地，将其绑定到一个video标签上输出
					pc.onaddstream = function(event) {
						console.log("Remote stream added.");
						trace("Remote stream added.");
						document.getElementById('remoteVideo').src = URL.createObjectURL(event.stream);
						// 启动全屏!
						HugeVideo();
					}
					pc.onremovestream = onRemoteStreamRemoved;
					console.log("Created RTCPeerConnnection with config \"" + JSON.stringify(pc_config) + "\". for ");
					trace("Created RTCPeerConnnection with config \"" + JSON.stringify(pc_config) + "\". for ");
					//setLocalStream(connectionId);//解除注释将可以双端通信 不过延迟就高了
				} catch(e) {
					console.log("Failed to create PeerConnection with " + connectionId + ", exception: " + e.message);
					trace("Failed to create PeerConnection with " + connectionId + ", exception: " + e.message);
				}

			}

			function setLocalStream(connectionId) {
				// 获取本地音频和视频流
				navigator.getUserMedia(constraints, function(stream) {
					//绑定本地媒体流到video标签用于输出
					document.getElementById('localVideo').src = URL.createObjectURL(stream);
					//向PeerConnection中加入需要发送的流
					pc.addStream(stream);
					//如果是发起方则发送一个offer信令
					pc.createOffer(function sendOfferFn(desc) {
						pc.setLocalDescription(desc);
						var data = JSON.stringify(desc);
						sendToPeer(connectionId, data);
					}, function(error) {
						console.log('Failure callback: ' + error);
						trace('Failure callback: ' + error);
					});
				}, function(error) {
					//处理媒体流创建失败错误
					console.log('getUserMedia error: ' + error);
					trace('getUserMedia error: ' + error);
				});

			}
			//添加新加入的peer到本地
			function handleServerNotification(data) {
				console.log("Server notification: " + data);
				trace("Server notification: " + data);
				var parsed = data.split(',');
				if(parseInt(parsed[2]) != 0)
					other_peers[parseInt(parsed[1])] = parsed[0];
			}
			//如果是一个ICE的候选，则将其加入到PeerConnection中，否则设定对方的session描述为传递过来的描述
			function handlePeerMessage(peer_id, data) {
				var dataJson = JSON.parse(data);
				if(data.search("offer") != -1) {
					//json:{"sdp":xxx,type:"offer"}
					createPeerConnection(peer_id);
					pc.setRemoteDescription(new RTCSessionDescription(dataJson));
					pc.createAnswer(function(sessionDescription) {
						var answerData = JSON.stringify(sessionDescription);
						console.log("answer:" + answerData);
						trace("answer:" + answerData);
						pc.setLocalDescription(sessionDescription);
						sendToPeer(peer_id, answerData);
					}, function(error) {
						console.log('Failure callback: ' + error);
						trace('Failure callback: ' + error);
					});
				} else {
					//It is a candidate
					var candidate = new RTCIceCandidate({
						sdpMLineIndex: dataJson.sdpMLineIndex,
						candidate: dataJson.candidate
					});
					pc.addIceCandidate(candidate);
				}
			}

			function GetIntHeader(r, name) {
				var val = r.getResponseHeader(name);
				return val != null && val.length ? parseInt(val) : -1;
			}
			//等待服务器返回，当出现以下情况或超时才会返回 
			//1.其他peer连接上server会返回peer的数据{peerName,peerID,xx};用于本地添加
			//本地响应handleServerNotification
			//2.其他peer点击my_name(即发送 发送-接收视频 请求)，返回 一个ice的候选或者offer
			//	{
			// "candidate" : "candidate:1918330882 1 udp 2122260223 192.168.253.1 55710 typ host generation 0 ufrag YUtt network-id 4 network-cost 50",
			// "sdpMLineIndex" : 0,
			// "sdpMid" : "audio"
			//} this is ice
			//本地响应handlePeerMessage
			function hangingGetCallback() {
				try {
					if(hangingGet.readyState != 4)
						return; //why?
					if(hangingGet.status != 200) {
						console.log("server error: " + hangingGet.statusText);
						trace("server error: " + hangingGet.statusText);
						disconnect();
					} else {
						var peer_id = GetIntHeader(hangingGet, "Pragma");

						if(peer_id == my_id) {
							console.log("handleServerNotification:" + hangingGet.responseText);
							trace("handleServerNotification:" + hangingGet.responseText);
							handleServerNotification(hangingGet.responseText);
						} else {
							console.log("handlePeerMessage:" + hangingGet.responseText);
							trace("handlePeerMessage:" + hangingGet.responseText);
							handlePeerMessage(peer_id, hangingGet.responseText);
						}
					}

					if(hangingGet) {
						hangingGet.abort();
						hangingGet = null;
					}

					if(my_id != -1)
						window.setTimeout(startHangingGet, 0);
				} catch(e) {
					console.log("Hanging get error: " + e.description);
					trace("Hanging get error: " + e.description);
				}
			}
			//继续把my_id发给server 当其他peer连接服务器的时候其他peer就可以获取my_id
			function startHangingGet() {
				try {
					hangingGet = new XMLHttpRequest();
					hangingGet.onreadystatechange = hangingGetCallback;
					hangingGet.ontimeout = onHangingGetTimeout;
					hangingGet.open("GET", server + "/wait?peer_id=" + my_id, true);
					hangingGet.send();
				} catch(e) {
					console.log("error" + e.description);
					trace("error" + e.description);
				}
			}
			//如果超时则继续发送startHangingGet请求
			function onHangingGetTimeout() {
				console.log("hanging get timeout. issuing again.");
				trace("hanging get timeout. issuing again.");
				hangingGet.abort();
				hangingGet = null;
				if(my_id != -1)
					window.setTimeout(startHangingGet, 0);
			}
			//server返回my_id(服务器已递增的方式生成id)和远端peer的id
			//那如果browser先连接，没有其他peer，该方法返回时没有远端peer的id 后面是哪里获取的呢？
			//所以它又做了一个startHangingGet();
			//通过handleServerNotification 得到,log:Server notification: zhengjx@X-CDN-zhengjx,2,1
			function signInCallback() {
				try {
					console.log("request.readyState:" + request.readyState);
					trace("request.readyState:" + request.readyState);
					if(request.readyState == 4) {
						if(request.status == 200) {
							var peers = request.responseText.split("\n");
							my_id = parseInt(peers[0].split(',')[1]);
							console.log("My id: " + my_id); //My id 1
							trace("My id: " + my_id); //My id 1
							//Peer 1: zhengjx@X-CDN-zhengjx,2,parsed[2]没用到 
							for(var i = 1; i < peers.length; ++i) {
								if(peers[i].length > 0) {
									console.log("Peer " + i + ": " + peers[i]);
									trace("Peer " + i + ": " + peers[i]);
									var parsed = peers[i].split(',');
									other_peers[parseInt(parsed[1])] = parsed[0];
								}
							}
							startHangingGet();
							request = null;
						}
					}
				} catch(e) {
					console.log("error: " + e.description);
					trace("error: " + e.description);
				}
			}
			//注册，把自己的localName发给server
			function signIn() {
				try {
					request = new XMLHttpRequest();
					request.onreadystatechange = signInCallback;
					request.open("GET", server + "/sign_in?" + localName, true);
					request.send();
				} catch(e) {
					console.log("error: " + e.description);
					trace("error: " + e.description);
				}
			}

			function connect() {
				localName = document.getElementById("local").value.toLowerCase();
				server = document.getElementById("server").value.toLowerCase();
				if(localName.length == 0) {
					alert("I need a name please.");
					document.getElementById("local").focus();
				} else {
					document.getElementById("connect").disabled = true;
					document.getElementById("disconnect").disabled = false;
					//document.getElementById("send").disabled = false;
					signIn();
				}
			}

			function disconnect() {
				if(request) {
					request.abort();
					request = null;
				}

				if(hangingGet) {
					hangingGet.abort();
					hangingGet = null;
				}

				if(my_id != -1) {
					request = new XMLHttpRequest();
					request.open("GET", server + "/sign_out?peer_id=" + my_id, false);
					request.send();
					request = null;
					my_id = -1;
				}

				document.getElementById("connect").disabled = false;
				document.getElementById("disconnect").disabled = true;
				//document.getElementById("send").disabled = true;
			}

			function HugeVideo() {
				var mVideo = document.getElementById("remoteVideo");
				console.log("设置宽为：" + window.screen.width);
				mVideo.width = window.screen.width;
			}

			function smallVideo() {
				var mVideo = document.getElementById("remoteVideo");
				mVideo.width = 320;
				mVideo.height = 240;
			}

			function transfVideo() {
				$("#remoteVideo").addClass("trans90");
			}

			function notransfVideo() {
				$("#remoteVideo").removeClass("trans90");
			}

			function fullScreen() {
				var remoteVideo = document.getElementById('remoteVideo');
				if(remoteVideo.videoWidth > remoteVideo.videoHeight) {
					console.log("需要旋转")
						//					$("#remoteVideo").addClass("trans90");
				} else {
					//					$("#remoteVideo").addClass("trans90");
					console.log("不需旋转")
				}

				launchFullScreen(remoteVideo);

			}
		</script>
	</head>

	<body id="body">
		<!--<video id="localVideo" autoplay></video><br> Remote: <br>-->
		<div class="container">
			<video id="remoteVideo" autoplay width="100%" height="100%">
				<p>您的浏览器不支持该标签</p>
			</video>
		</div>
		<div class="layout">
			Server: <input type="text" id="server" value="http://172.27.35.1:8888" /><br> Your name: <input type="text" id="local" value="my_name" />
			<button id="connect" onclick="connect();">Connect</button>
			<button disabled="true" id="disconnect" onclick="disconnect();">Disconnect</button>
			<button onclick="HugeVideo()">放大</button>
			<button onclick="smallVideo()">缩小</button>
			<button onclick="fullScreen()">全屏</button>
			<button onclick="transfVideo()">旋转</button>
			<button onclick="notransfVideo()">还原旋转</button>
		</div>
		<pre id="debug">
		</pre>

	</body>
	<script>
		console.log(" 屏幕分辨率的高：" + window.screen.height + "\n" + " 屏幕分辨率的宽：" + window.screen.width + "\n")
	</script>

</html>